/**
 * Sealos对象存储客户端
 * 适配微信小程序环境
 */

const { S3_CONFIG, getEndpoint, PRESIGNED_URL_EXPIRES } = require('./config');
const { generateV4Headers, generatePresignedUrl } = require('./signature');

/**
 * 上传文件到对象存储
 * @param {Object} options 上传选项
 * @param {string} options.filePath 小程序临时文件路径
 * @param {string} options.objectKey 对象键
 * @param {string} options.contentType 内容类型
 * @param {Function} options.onProgress 上传进度回调
 * @returns {Promise<Object>} 上传结果
 */
function uploadFile(options) {
  const { filePath, objectKey, contentType = 'application/octet-stream', onProgress } = options;
  const bucketName = S3_CONFIG.bucketName;
  const endpoint = getEndpoint();
  
  return new Promise((resolve, reject) => {
    // 生成授权头
    const headers = generateV4Headers({
      method: 'PUT',
      key: objectKey,
      headers: {
        'Content-Type': contentType
      }
    });
    
    // 使用微信上传API
    const uploadTask = wx.uploadFile({
      url: `${endpoint}/${bucketName}/${objectKey}`,
      filePath: filePath,
      name: 'file',
      header: headers,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 生成对象URL
          const fileUrl = generatePresignedUrl({
            method: 'GET',
            key: objectKey,
            expires: PRESIGNED_URL_EXPIRES
          });
          
          resolve({
            statusCode: res.statusCode,
            objectKey: objectKey,
            url: fileUrl
          });
        } else {
          reject(new Error(`上传失败: HTTP ${res.statusCode}`));
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
    
    // 监听上传进度
    if (onProgress && uploadTask) {
      uploadTask.onProgressUpdate((res) => {
        onProgress({
          progress: res.progress,
          totalBytesSent: res.totalBytesSent,
          totalBytesExpectedToSend: res.totalBytesExpectedToSend
        });
      });
    }
  });
}

/**
 * 下载文件
 * @param {Object} options 下载选项
 * @param {string} options.objectKey 对象键
 * @param {string} options.filePath 保存路径
 * @param {Function} options.onProgress 下载进度回调
 * @returns {Promise<Object>} 下载结果
 */
function downloadFile(options) {
  const { objectKey, filePath, onProgress } = options;
  
  return new Promise((resolve, reject) => {
    // 生成预签名URL
    const presignedUrl = generatePresignedUrl({
      method: 'GET',
      key: objectKey,
      expires: PRESIGNED_URL_EXPIRES
    });
    
    // 使用微信下载API
    const downloadTask = wx.downloadFile({
      url: presignedUrl,
      filePath: filePath,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve({
            statusCode: res.statusCode,
            tempFilePath: res.tempFilePath,
            filePath: filePath
          });
        } else {
          reject(new Error(`下载失败: HTTP ${res.statusCode}`));
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
    
    // 监听下载进度
    if (onProgress && downloadTask) {
      downloadTask.onProgressUpdate((res) => {
        onProgress({
          progress: res.progress,
          totalBytesWritten: res.totalBytesWritten,
          totalBytesExpectedToWrite: res.totalBytesExpectedToWrite
        });
      });
    }
  });
}

/**
 * 获取对象详情
 * @param {string} objectKey 对象键
 * @returns {Promise<Object>} 对象详情
 */
function getObjectInfo(objectKey) {
  const bucketName = S3_CONFIG.bucketName;
  const endpoint = getEndpoint();
  
  return new Promise((resolve, reject) => {
    // 生成授权头
    const headers = generateV4Headers({
      method: 'HEAD',
      key: objectKey
    });
    
    // 发起HEAD请求
    wx.request({
      url: `${endpoint}/${bucketName}/${objectKey}`,
      method: 'HEAD',
      header: headers,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 返回对象元数据
          resolve({
            statusCode: res.statusCode,
            objectKey: objectKey,
            metadata: res.header,
            contentLength: parseInt(res.header['content-length'] || '0'),
            contentType: res.header['content-type'],
            etag: res.header['etag']
          });
        } else if (res.statusCode === 404) {
          reject(new Error('对象不存在'));
        } else {
          reject(new Error(`获取对象详情失败: HTTP ${res.statusCode}`));
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
}

/**
 * 删除对象
 * @param {string} objectKey 对象键
 * @returns {Promise<Object>} 删除结果
 */
function deleteObject(objectKey) {
  const bucketName = S3_CONFIG.bucketName;
  const endpoint = getEndpoint();
  
  return new Promise((resolve, reject) => {
    // 生成授权头
    const headers = generateV4Headers({
      method: 'DELETE',
      key: objectKey
    });
    
    // 发起DELETE请求
    wx.request({
      url: `${endpoint}/${bucketName}/${objectKey}`,
      method: 'DELETE',
      header: headers,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve({
            statusCode: res.statusCode,
            objectKey: objectKey,
            deleted: true
          });
        } else {
          reject(new Error(`删除对象失败: HTTP ${res.statusCode}`));
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
}

/**
 * 生成对象访问URL
 * @param {string} objectKey 对象键
 * @param {number} expires 过期时间（秒）
 * @returns {string} 访问URL
 */
function getObjectUrl(objectKey, expires = PRESIGNED_URL_EXPIRES) {
  return generatePresignedUrl({
    method: 'GET',
    key: objectKey,
    expires: expires
  });
}

module.exports = {
  uploadFile,
  downloadFile,
  getObjectInfo,
  deleteObject,
  getObjectUrl
};